﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Bohdan.Arch
{
    public abstract class InVal<T>
    {
        public abstract T Data { get; }

        public static InVal<T> Direct(T data)
        {
            return new DirectValue<T>(data);
        }

        public static InVal<T> Lazy(Func<T> f)
        {
            return new LazyValue<T>(f);
        }

        public static implicit operator InVal<T>(T data)
        {
            return new DirectValue<T>(data);
        }

        public static implicit operator T(InVal<T> iv)
        {
            return iv.Data;
        }
    }


    internal class DirectValue<T> : InVal<T>
    {
        T _data;

        public DirectValue(T data)
        {
            _data = data;
        }

        public override T Data
        {
            get
            {
                return _data;
            }
        }
    }



    internal class LazyValue<T> : InVal<T>
    {
        Func<T> _f;

        public LazyValue(Func<T> f)
        {
            _f = f;
        }

        public override T Data
        {
            get
            {
                return _f();
            }
        }
    }
}
